package cn.ac.sec.oil.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import cn.ac.sec.framework.db.SqlUtils;
import cn.ac.sec.oil.data_analysis.protocol.ProtocolAnalysis;

/**
 * 功能：当socket建立连接或接收到消息时触发调用
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter  {

	private static final Logger LOG = Logger.getLogger(NettyServerHandler.class);
	ProtocolAnalysis pAnalysis = new ProtocolAnalysis(); //数据协议解析与处理模块
	String[] result = new String[4]; //用于保存数据的处理结果，分为2个部分

	public void channelRead(ChannelHandlerContext ctx, Object body) throws UnsupportedEncodingException {
		ByteBuf buf = (ByteBuf) body;
		byte[] req = new byte[buf.readableBytes()];
		buf.readBytes(req);
		String msg = bytesToHexString(req);
		LOG.info(msg);
		try {
			SqlUtils.update("INSERT INTO messages (client, message) values (?,?)", ctx.channel().remoteAddress().toString(), msg); //将数据写入数据库
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		result = pAnalysis.dataAnalysis(ctx.channel().remoteAddress() + ";" + msg).split("[:]");
		if (result[0].equals("result")) {
			ctx.writeAndFlush(result[1] + "\n"); // 返回客户端一次测量的数据处理结果
			LOG.info("向客户端返回本次测量数据处理结果: " + result[1] + "\n");
		}	
		
	}
	
	/*
	 * 覆盖 channelActive方法 在channel被启用的时候触发 (在建立连接的时候)
	 * 不能随便向设备发送数据
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {

		LOG.info(ctx.channel().remoteAddress() + "连入服务器！");
		//ctx.writeAndFlush("Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n");

		super.channelActive(ctx);
	} 
	
	/**
	 * 功能：处理设备掉线等异常
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		
		ctx.flush();
		LOG.info(ctx.channel().remoteAddress() + "异常离线 ...");
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		
		LOG.info(ctx.channel().remoteAddress() + "离线 ...");
	}
	
	public static String bytesToHexString(byte[] src){  
	    StringBuilder stringBuilder = new StringBuilder("");  
	    if (src == null || src.length <= 0) {  
	        return null;  
	    }  
	    for (int i = 0; i < src.length; i++) {  
	        int v = src[i] & 0xFF;  
	        String hv = Integer.toHexString(v);  
	        if (hv.length() < 2) {  
	            stringBuilder.append(0);  
	        }  
	        stringBuilder.append(hv).append(" ");  
	    }  
	    return stringBuilder.toString();  
	}  
}
